package server;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;


import Utility.ClientUtilities;
import Utility.Constants;
import Utility.Host;

/**
 * Server that acts as : (PAXOS SERVER)
 * 
 *  1. PROPOSER - Proposes request (N,V)
 *  2. ACCEPTOR - Accepts the proposal request
 *  3. LEARNER - Learns the accepted proposals
 *
 */
public class Server1{
	int serverId = 1;
	
	Socket clientSocket;
	ServerSocket serverSocket;
	long failureEndTimeInMillis = 0;
	//static boolean[] locks_Array;
	
	public static void main(String args[]) throws IOException,ClassNotFoundException {
		Server1 serverSide = new Server1();
		serverSide.startServer();
	}

	/**
	 * Method to start the server
	 * 
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */

	public void startServer() throws IOException, ClassNotFoundException {
		Host server1 = ClientUtilities.serversMap.get(serverId);
		File f = new File(System.getProperty("user.dir")+File.separator+"locksfile"+serverId);
		if(f.exists()){
				f.delete();
		}
		try {
			System.out.println("[SERVER-1] Listening for clients");
			serverSocket = new ServerSocket(Integer.parseInt(server1.getPortNumber()));
		} catch (IOException e) {
			System.out.println("Could not find connection");
			e.printStackTrace();
		}
		try {
			// Run this server until  it get killed manually. 
			// This keeps accepting client connections and spawns a new thread to take over task.
			while(true){
				clientSocket = serverSocket.accept();
				System.out.println(this.getClass().getSimpleName() + " Accepted client connection from host : " + clientSocket.getInetAddress().getHostAddress());	
				PaxosServerThread paxosServerThread = new PaxosServerThread(clientSocket,serverId, continueProcessingRequest());
				Thread paxosThread = new Thread(paxosServerThread);
				paxosThread.start();
			}
		} catch (Exception e) {
			System.out.println("Accept failed");
			e.printStackTrace();
		}
		System.out.println("[SERVER-1] Making i/o connections :) ");
	}
	
	private boolean continueProcessingRequest()
	{
		boolean continueProcessing = false;
		long currentTimeInMillis = System.currentTimeMillis();
		if (currentTimeInMillis > failureEndTimeInMillis )
		{
			Random generateRandomNumber = new Random();
			int randomNumber = generateRandomNumber.nextInt(100);
			//System.out.println("Failure Thread percentage generated " + randomNumber);
			if (randomNumber > Constants.failurePercentage)
				continueProcessing = true;
			else
				failureEndTimeInMillis = currentTimeInMillis + Constants.FailureWindowInMillis;
		}
		return continueProcessing;
	}
}
